/* eslint-disable */
import type { ChanBackupSnapshot } from './lightning';

export interface GenSeedRequest {
    /**
     * aezeed_passphrase is an optional user provided passphrase that will be used
     * to encrypt the generated aezeed cipher seed. When using REST, this field
     * must be encoded as base64.
     */
    aezeedPassphrase: Uint8Array | string;
    /**
     * seed_entropy is an optional 16-bytes generated via CSPRNG. If not
     * specified, then a fresh set of randomness will be used to create the seed.
     * When using REST, this field must be encoded as base64.
     */
    seedEntropy: Uint8Array | string;
}

export interface GenSeedResponse {
    /**
     * cipher_seed_mnemonic is a 24-word mnemonic that encodes a prior aezeed
     * cipher seed obtained by the user. This field is optional, as if not
     * provided, then the daemon will generate a new cipher seed for the user.
     * Otherwise, then the daemon will attempt to recover the wallet state linked
     * to this cipher seed.
     */
    cipherSeedMnemonic: string[];
    /**
     * enciphered_seed are the raw aezeed cipher seed bytes. This is the raw
     * cipher text before run through our mnemonic encoding scheme.
     */
    encipheredSeed: Uint8Array | string;
}

export interface InitWalletRequest {
    /**
     * wallet_password is the passphrase that should be used to encrypt the
     * wallet. This MUST be at least 8 chars in length. After creation, this
     * password is required to unlock the daemon. When using REST, this field
     * must be encoded as base64.
     */
    walletPassword: Uint8Array | string;
    /**
     * cipher_seed_mnemonic is a 24-word mnemonic that encodes a prior aezeed
     * cipher seed obtained by the user. This may have been generated by the
     * GenSeed method, or be an existing seed.
     */
    cipherSeedMnemonic: string[];
    /**
     * aezeed_passphrase is an optional user provided passphrase that will be used
     * to encrypt the generated aezeed cipher seed. When using REST, this field
     * must be encoded as base64.
     */
    aezeedPassphrase: Uint8Array | string;
    /**
     * recovery_window is an optional argument specifying the address lookahead
     * when restoring a wallet seed. The recovery window applies to each
     * individual branch of the BIP44 derivation paths. Supplying a recovery
     * window of zero indicates that no addresses should be recovered, such after
     * the first initialization of the wallet.
     */
    recoveryWindow: number;
    /**
     * channel_backups is an optional argument that allows clients to recover the
     * settled funds within a set of channels. This should be populated if the
     * user was unable to close out all channels and sweep funds before partial or
     * total data loss occurred. If specified, then after on-chain recovery of
     * funds, lnd begin to carry out the data loss recovery protocol in order to
     * recover the funds in each channel from a remote force closed transaction.
     */
    channelBackups: ChanBackupSnapshot | undefined;
    /**
     * stateless_init is an optional argument instructing the daemon NOT to create
     * any *.macaroon files in its filesystem. If this parameter is set, then the
     * admin macaroon returned in the response MUST be stored by the caller of the
     * RPC as otherwise all access to the daemon will be lost!
     */
    statelessInit: boolean;
    /**
     * extended_master_key is an alternative to specifying cipher_seed_mnemonic and
     * aezeed_passphrase. Instead of deriving the master root key from the entropy
     * of an aezeed cipher seed, the given extended master root key is used
     * directly as the wallet's master key. This allows users to import/use a
     * master key from another wallet. When doing so, lnd still uses its default
     * SegWit only (BIP49/84) derivation paths and funds from custom/non-default
     * derivation paths will not automatically appear in the on-chain wallet. Using
     * an 'xprv' instead of an aezeed also has the disadvantage that the wallet's
     * birthday is not known as that is an information that's only encoded in the
     * aezeed, not the xprv. Therefore a birthday needs to be specified in
     * extended_master_key_birthday_timestamp or a "safe" default value will be
     * used.
     */
    extendedMasterKey: string;
    /**
     * extended_master_key_birthday_timestamp is the optional unix timestamp in
     * seconds to use as the wallet's birthday when using an extended master key
     * to restore the wallet. lnd will only start scanning for funds in blocks that
     * are after the birthday which can speed up the process significantly. If the
     * birthday is not known, this should be left at its default value of 0 in
     * which case lnd will start scanning from the first SegWit block (481824 on
     * mainnet).
     */
    extendedMasterKeyBirthdayTimestamp: string;
    /**
     * watch_only is the third option of initializing a wallet: by importing
     * account xpubs only and therefore creating a watch-only wallet that does not
     * contain any private keys. That means the wallet won't be able to sign for
     * any of the keys and _needs_ to be run with a remote signer that has the
     * corresponding private keys and can serve signing RPC requests.
     */
    watchOnly: WatchOnly | undefined;
    /**
     * macaroon_root_key is an optional 32 byte macaroon root key that can be
     * provided when initializing the wallet rather than letting lnd generate one
     * on its own.
     */
    macaroonRootKey: Uint8Array | string;
}

export interface InitWalletResponse {
    /**
     * The binary serialized admin macaroon that can be used to access the daemon
     * after creating the wallet. If the stateless_init parameter was set to true,
     * this is the ONLY copy of the macaroon and MUST be stored safely by the
     * caller. Otherwise a copy of this macaroon is also persisted on disk by the
     * daemon, together with other macaroon files.
     */
    adminMacaroon: Uint8Array | string;
}

export interface WatchOnly {
    /**
     * The unix timestamp in seconds of when the master key was created. lnd will
     * only start scanning for funds in blocks that are after the birthday which
     * can speed up the process significantly. If the birthday is not known, this
     * should be left at its default value of 0 in which case lnd will start
     * scanning from the first SegWit block (481824 on mainnet).
     */
    masterKeyBirthdayTimestamp: string;
    /**
     * The fingerprint of the root key (also known as the key with derivation path
     * m/) from which the account public keys were derived from. This may be
     * required by some hardware wallets for proper identification and signing. The
     * bytes must be in big-endian order.
     */
    masterKeyFingerprint: Uint8Array | string;
    /**
     * The list of accounts to import. There _must_ be an account for all of lnd's
     * main key scopes: BIP49/BIP84 (m/49'/0'/0', m/84'/0'/0', note that the
     * coin type is always 0, even for testnet/regtest) and lnd's internal key
     * scope (m/1017'/<coin_type>'/<account>'), where account is the key family as
     * defined in `keychain/derivation.go` (currently indices 0 to 9).
     */
    accounts: WatchOnlyAccount[];
}

export interface WatchOnlyAccount {
    /**
     * Purpose is the first number in the derivation path, must be either 49, 84
     * or 1017.
     */
    purpose: number;
    /**
     * Coin type is the second number in the derivation path, this is _always_ 0
     * for purposes 49 and 84. It only needs to be set to 1 for purpose 1017 on
     * testnet or regtest.
     */
    coinType: number;
    /**
     * Account is the third number in the derivation path. For purposes 49 and 84
     * at least the default account (index 0) needs to be created but optional
     * additional accounts are allowed. For purpose 1017 there needs to be exactly
     * one account for each of the key families defined in `keychain/derivation.go`
     * (currently indices 0 to 9)
     */
    account: number;
    /** The extended public key at depth 3 for the given account. */
    xpub: string;
}

export interface UnlockWalletRequest {
    /**
     * wallet_password should be the current valid passphrase for the daemon. This
     * will be required to decrypt on-disk material that the daemon requires to
     * function properly. When using REST, this field must be encoded as base64.
     */
    walletPassword: Uint8Array | string;
    /**
     * recovery_window is an optional argument specifying the address lookahead
     * when restoring a wallet seed. The recovery window applies to each
     * individual branch of the BIP44 derivation paths. Supplying a recovery
     * window of zero indicates that no addresses should be recovered, such after
     * the first initialization of the wallet.
     */
    recoveryWindow: number;
    /**
     * channel_backups is an optional argument that allows clients to recover the
     * settled funds within a set of channels. This should be populated if the
     * user was unable to close out all channels and sweep funds before partial or
     * total data loss occurred. If specified, then after on-chain recovery of
     * funds, lnd begin to carry out the data loss recovery protocol in order to
     * recover the funds in each channel from a remote force closed transaction.
     */
    channelBackups: ChanBackupSnapshot | undefined;
    /**
     * stateless_init is an optional argument instructing the daemon NOT to create
     * any *.macaroon files in its file system.
     */
    statelessInit: boolean;
}

export interface UnlockWalletResponse {}

export interface ChangePasswordRequest {
    /**
     * current_password should be the current valid passphrase used to unlock the
     * daemon. When using REST, this field must be encoded as base64.
     */
    currentPassword: Uint8Array | string;
    /**
     * new_password should be the new passphrase that will be needed to unlock the
     * daemon. When using REST, this field must be encoded as base64.
     */
    newPassword: Uint8Array | string;
    /**
     * stateless_init is an optional argument instructing the daemon NOT to create
     * any *.macaroon files in its filesystem. If this parameter is set, then the
     * admin macaroon returned in the response MUST be stored by the caller of the
     * RPC as otherwise all access to the daemon will be lost!
     */
    statelessInit: boolean;
    /**
     * new_macaroon_root_key is an optional argument instructing the daemon to
     * rotate the macaroon root key when set to true. This will invalidate all
     * previously generated macaroons.
     */
    newMacaroonRootKey: boolean;
}

export interface ChangePasswordResponse {
    /**
     * The binary serialized admin macaroon that can be used to access the daemon
     * after rotating the macaroon root key. If both the stateless_init and
     * new_macaroon_root_key parameter were set to true, this is the ONLY copy of
     * the macaroon that was created from the new root key and MUST be stored
     * safely by the caller. Otherwise a copy of this macaroon is also persisted on
     * disk by the daemon, together with other macaroon files.
     */
    adminMacaroon: Uint8Array | string;
}

/**
 * WalletUnlocker is a service that is used to set up a wallet password for
 * lnd at first startup, and unlock a previously set up wallet.
 */
export interface WalletUnlocker {
    /**
     * GenSeed is the first method that should be used to instantiate a new lnd
     * instance. This method allows a caller to generate a new aezeed cipher seed
     * given an optional passphrase. If provided, the passphrase will be necessary
     * to decrypt the cipherseed to expose the internal wallet seed.
     *
     * Once the cipherseed is obtained and verified by the user, the InitWallet
     * method should be used to commit the newly generated seed, and create the
     * wallet.
     */
    genSeed(request?: DeepPartial<GenSeedRequest>): Promise<GenSeedResponse>;
    /**
     * InitWallet is used when lnd is starting up for the first time to fully
     * initialize the daemon and its internal wallet. At the very least a wallet
     * password must be provided. This will be used to encrypt sensitive material
     * on disk.
     *
     * In the case of a recovery scenario, the user can also specify their aezeed
     * mnemonic and passphrase. If set, then the daemon will use this prior state
     * to initialize its internal wallet.
     *
     * Alternatively, this can be used along with the GenSeed RPC to obtain a
     * seed, then present it to the user. Once it has been verified by the user,
     * the seed can be fed into this RPC in order to commit the new wallet.
     */
    initWallet(
        request?: DeepPartial<InitWalletRequest>
    ): Promise<InitWalletResponse>;
    /**
     * lncli: `unlock`
     * UnlockWallet is used at startup of lnd to provide a password to unlock
     * the wallet database.
     */
    unlockWallet(
        request?: DeepPartial<UnlockWalletRequest>
    ): Promise<UnlockWalletResponse>;
    /**
     * lncli: `changepassword`
     * ChangePassword changes the password of the encrypted wallet. This will
     * automatically unlock the wallet database if successful.
     */
    changePassword(
        request?: DeepPartial<ChangePasswordRequest>
    ): Promise<ChangePasswordResponse>;
}

type Builtin =
    | Date
    | Function
    | Uint8Array
    | string
    | number
    | boolean
    | undefined;

type DeepPartial<T> = T extends Builtin
    ? T
    : T extends Array<infer U>
    ? Array<DeepPartial<U>>
    : T extends ReadonlyArray<infer U>
    ? ReadonlyArray<DeepPartial<U>>
    : T extends {}
    ? { [K in keyof T]?: DeepPartial<T[K]> }
    : Partial<T>;
